package com.drakulo.games.ais.core.building;

import java.math.BigDecimal;

import com.drakulo.games.ais.core.Resource;

/**
 * <h1>Represents a building</h1>
 * 
 * @author Drakulo
 * 
 */
public class Building {
	/** The building level */
	protected int level;

	/**
	 * The building state. If this var is set to false, that's because the
	 * building needs more ressources than there is in the warehouse.
	 */
	private boolean canRun;

	/** A building can be shut down by the player */
	private boolean isRunning;

	/** Building X coordinate */
	private int x;

	/** Building Y coordinate */
	private int y;

	/** Flag indicating if the building is currently upgrading */
	private boolean isUpgrading;

	/** Flag indicating if the building is currently under construction */
	private boolean isUnderConstruction;

	/** The building type, defining its properties */
	private BuildingType type;

	/**
	 * Default empty constructor
	 */
	public Building(BuildingType type) {
		this(type, 0, 0);
	}

	/**
	 * Constructor
	 */
	public Building(BuildingType type, int x, int y) {
		this(type, x, y, 1);
	}

	/**
	 * Building constructor
	 * 
	 * @param level
	 *            the building start level
	 */
	public Building(BuildingType type, int x, int y, int level) {
		this.type = type;
		this.level = level;
		this.canRun = true;
		this.x = x;
		this.y = y;
	}

	/**
	 * @return true if the building can run (it has enought resources to run)
	 */
	public boolean canRun() {
		return this.canRun;
	}

	/**
	 * Returns the total storage space provided by the bulding for the given
	 * ressource type
	 * 
	 * @param type
	 *            the ressource type
	 * @return the amount of space
	 */
	public BigDecimal getStoreSpaceFor(Resource type) {
		BigDecimal value = BuildingHelper.getStoreSpaceOf(this).get(type);

		if (value == null) {
			return BigDecimal.ZERO;
		}
		return value;
	}

	/**
	 * Starts the building production
	 */
	public void run() {
		this.isRunning = true;
	}

	/**
	 * Stops the building production
	 */
	public void stop() {
		this.isRunning = false;
	}

	/**
	 * Initializes if the building can run
	 * 
	 * @param canRun
	 *            the flag
	 */
	public void setCanRun(boolean canRun) {
		this.canRun = canRun;
	}

	/**
	 * @return true if the building can ans is running
	 */
	public boolean isRunning() {
		return this.isRunning && this.canRun;
	}

	/**
	 * @return the building type
	 */
	public BuildingType getType() {
		return this.type;
	}

	public int getLevel() {
		return this.level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public Building clone() {
		Building b = new Building(this.type);
		b.canRun = this.canRun;
		b.isRunning = this.isRunning;
		b.level = this.level;
		b.x = this.x;
		b.y = this.y;
		return b;
	}

	public int getX() {
		return this.x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return this.y;
	}

	public void setY(int y) {
		this.y = y;
	}

	public BuildingCategory getCategory() {
		return this.type.getCategory();
	}

	public void upgrade() {
		this.level++;
	}

	public boolean isUpgrading() {
		return this.isUpgrading;
	}

	public void setUpgrading(boolean isUpgrading) {
		this.isUpgrading = isUpgrading;
	}

	public boolean isUnderConstruction() {
		return this.isUnderConstruction;
	}

	public void setUnderConstruction(boolean isUnderConstruction) {
		this.isUnderConstruction = isUnderConstruction;
	}

	public String getI18n() {
		return this.type.getI18n();
	}
}
